﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using JQuery.WebKit.WebCommon;

namespace JQuery.WebKit.Base
{
    public enum PostType
    {
        Value = 0,
        Text = 1,
        TextAndValue = 2
    }

    [ToolboxItem(typeof(JControl))]
    public abstract class JControl : HtmlGenericControl
    {
        internal abstract PostType PostType { get; }
        internal List<string> _scripts;

        public new JPage Page { get { return base.Page as JPage; } }
        public virtual string Name { get; set; }
        public virtual object Value { get; set; }

        public virtual Unit Width { get; set; }

        public virtual bool? Required { get; set; }

        public virtual bool Enabled
        {
            get { return !base.Disabled; }
            set { base.Disabled = !value; }
        }

        internal ValidationFlags ValidationFlags { get; set; }
        internal int Length { get; set; }
        internal int Precision { get; set; }

        public virtual string CssClass { get; set; }

        public JControl()
            : base()
        {
            _scripts = new List<string>();
        }

        public JControl(string tag)
            : base(tag)
        {
            _scripts = new List<string>();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (Page.IsPostBack)
            {
                Validate(Value);
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            this.Attributes.Add("meta", "jControl");
            this.Attributes.Add("jName", string.IsNullOrEmpty(Name) ? this.ClientID : Name);

            string postType = "";
            switch (PostType)
            {
                case Base.PostType.Value:
                    if (this as JImage == null)
                    {
                        this.Attributes.Add("value", Value != null ? Value.ToString() : string.Empty);
                        postType = "value";
                    }
                    break;
                case Base.PostType.Text:
                    if (Value != null)
                    {
                        base.Controls.Add(new LiteralControl(Value.ToString()));
                    }
                    postType = "text";
                    break;
                case Base.PostType.TextAndValue:
                    postType = "textandvalue";
                    break;
                default:
                    this.Attributes.Add("value", Value != null ? Value.ToString() : string.Empty);
                    postType = "value";
                    break;
            }
            this.Attributes.Add("post", postType);
            base.OnPreRender(e);
        }

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            if (!Visible && !DesignMode)
            {
                return;
            }
            if (DesignMode)
            {
                base.Render(writer); // render in normal way
                return;
            }
            if (this.TagName.ToLower() == "textarea")
            {
                this.InnerHtml = this.InnerHtml.Trim();
            }
            if (this.TagName.ToLower() != "input")
            {
                base.Render(writer); // render in normal way
            }
            else
            {
                writer.Write(HtmlTextWriter.TagLeftChar + this.TagName); // render opening tag
                if (string.IsNullOrWhiteSpace(this.Attributes["id"]))
                {
                    writer.WriteAttribute("id", this.ClientID);
                }
                Attributes.Render(writer);
                writer.Write(HtmlTextWriter.SelfClosingTagEnd); // render short closing tag   
            }

            writer.Write(Environment.NewLine);
        }

        public virtual string GetUpdaterScript(ScriptType scriptType)
        {
            return GetUpdaterScript(null, scriptType);
        }

        public virtual string GetUpdaterScript(string targetId, ScriptType scriptType)
        {
            string script = string.Empty;
            JUpdater pnl = null;
            if (string.IsNullOrWhiteSpace(targetId))
            {
                pnl = this.FindParent<JUpdater>();
            }
            else
            {
                pnl = (JUpdater)Page.FindControlRecursive(targetId, IDType.Server);
            }
            if (pnl == null)
            {
                throw new ApplicationException(string.Format("Cannot find updater for {0}", this.ClientID));
            }
            return pnl.GetScript(scriptType, this.ClientID);
        }

        public virtual bool Validate(object value)
        {
            return true;
        }

        public void AddBodyScript(string script)
        {
            Page.Resources.Add(new WebScriptResource(typeof(JControl), this.ClientID, ResourceType.Javascript, script, LoadEvent.NA) { Dependencies = new WebScriptResource[] { CommonResources.JQuery } });
        }

        public void AddJSResource(string resourceName, WebScriptResource[] dependencies)
        {
            Page.Resources.Add(new WebScriptResource(typeof(JPage), this.ClientID, ResourceType.Javascript, resourceName) { Dependencies = dependencies });
        }

        public void AddCSSResource(string resourceName)
        {
            Page.Resources.Add(new WebScriptResource(typeof(JPage), this.ClientID, ResourceType.Stylesheet, resourceName));
        }

        public void AddJQueryResource(string resourceName)
        {
            AddJSResource(resourceName, new WebScriptResource[] { CommonResources.JQueryUI });
        }
    }
}
